﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;

namespace LMSemir.Common
{
    /// <summary>
    /// 图形处理工具
    /// </summary>
    public class ImageUtils
    {
        /// <summary>
        /// 将 string 转 byte[] FromBase64
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public byte[] StringToBytesFromBase64(string inputString)
        {
            System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
            byte[] inputBytes = System.Convert.FromBase64String(inputString);
            return inputBytes;

        }

        /// <summary>
        /// 将 byte[] 转 string FromBase64
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public string BytesToStringFromBase64(byte[] inputBytes)
        {
            System.Text.UnicodeEncoding converter = new System.Text.UnicodeEncoding();
            string inputString = System.Convert.ToBase64String(inputBytes);
            return inputString;
        }
        /// <summary>
        /// 对给定的一个图片文件生成一个指定大小的缩略图。
        /// </summary>
        /// <param name="originalImage">图片的物理文件地址</param>
        /// <param name="thumMaxWidth">缩略图的宽度</param>
        /// <param name="thumMaxHeight">缩略图的高度</param>
        /// <returns>返回缩略图的Image对象</returns>
        public static System.Drawing.Image GetThumbNailImage(string imageFile, int thumMaxWidth, int thumMaxHeight)
        {
            System.Drawing.Image originalImage = null;
            System.Drawing.Image newImage = null;

            try
            {
                originalImage = System.Drawing.Image.FromFile(imageFile);
                newImage = GetThumbNailImage(originalImage, thumMaxWidth, thumMaxHeight);
            }
            catch { }
            finally
            {
                if (originalImage != null)
                {
                    originalImage.Dispose();
                    originalImage = null;
                }
            }

            return newImage;
        }
        /// <summary>
        /// 对给定的一个图片文件生成一个指定大小的缩略图，并将缩略图保存到指定位置。
        /// </summary>
        /// <param name="originalImageFile">图片的物理文件地址</param>
        /// <param name="thumbNailImageFile">缩略图的物理文件地址</param>
        /// <param name="thumMaxWidth">缩略图的宽度</param>
        /// <param name="thumMaxHeight">缩略图的高度</param>
        public static void MakeThumbNail(string originalImageFile, string thumbNailImageFile, int thumMaxWidth, int thumMaxHeight)
        {
            System.Drawing.Image newImage = GetThumbNailImage(originalImageFile, thumMaxWidth, thumMaxHeight);
            try
            {
                newImage.Save(thumbNailImageFile, ImageFormat.Jpeg);
            }
            catch
            { }
            finally
            {
                newImage.Dispose();
                newImage = null;
            }
        }
        /// <summary>
        /// 将一个图片的内存流调整为指定大小，并返回调整后的内存流。
        /// </summary>
        /// <param name="originalImageStream">原始图片的内存流</param>
        /// <param name="newWidth">新图片的宽度</param>
        /// <param name="newHeight">新图片的高度</param>
        /// <returns>返回调整后的图片的内存流</returns>
        public static MemoryStream ResizeImage(Stream originalImageStream, int newWidth, int newHeight)
        {
            MemoryStream newImageStream = null;
            System.Drawing.Image newImage = GetThumbNailImage(System.Drawing.Image.FromStream(originalImageStream, true), newWidth, newHeight);
            if (newImage != null)
            {
                newImageStream = new MemoryStream();
                newImage.Save(newImageStream, ImageFormat.Jpeg);
            }

            return newImageStream;
        }
        /// <summary>
        /// 将一个内存流保存为磁盘文件。
        /// </summary>
        /// <param name="stream">内存流</param>
        /// <param name="newFile">目标磁盘文件地址</param>
        public static void SaveStreamToFile(Stream stream, string newFile)
        {
            if (stream == null || stream.Length == 0 || string.IsNullOrEmpty(newFile))
            {
                return;
            }

            byte[] buffer = new byte[stream.Length];
            stream.Position = 0;
            stream.Read(buffer, 0, buffer.Length);
            FileStream fileStream = new FileStream(newFile, FileMode.OpenOrCreate, FileAccess.Write);
            fileStream.Write(buffer, 0, buffer.Length);
            fileStream.Flush();
            fileStream.Close();
            fileStream.Dispose();
        }
        /// <summary>
        /// 对一个指定的图片加上图片水印效果。
        /// </summary>
        /// <param name="imageFile">图片文件地址</param>
        /// <param name="waterImage">水印图片（Image对象）</param>
        public static void CreateImageWaterMark(string imageFile, System.Drawing.Image waterImage)
        {
            if (string.IsNullOrEmpty(imageFile) || !File.Exists(imageFile) || waterImage == null)
            {
                return;
            }

            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(imageFile);

            if (originalImage.Width - 10 < waterImage.Width || originalImage.Height - 10 < waterImage.Height)
            {
                return;
            }

            Graphics graphics = Graphics.FromImage(originalImage);

            int x = originalImage.Width - waterImage.Width - 10;
            int y = originalImage.Height - waterImage.Height - 10;
            int width = waterImage.Width;
            int height = waterImage.Height;

            graphics.DrawImage(waterImage, new Rectangle(x, y, width, height), 0, 0, width, height, GraphicsUnit.Pixel);
            graphics.Dispose();

            MemoryStream stream = new MemoryStream();
            originalImage.Save(stream, ImageFormat.Jpeg);
            originalImage.Dispose();

            System.Drawing.Image imageWithWater = System.Drawing.Image.FromStream(stream);

            imageWithWater.Save(imageFile);
            imageWithWater.Dispose();
        }

        /// <summary>
        /// 对给定的一个图片（Image对象）生成一个指定大小的缩略图。
        /// </summary>
        /// <param name="originalImage">原始图片</param>
        /// <param name="thumMaxWidth">缩略图的宽度</param>
        /// <param name="thumMaxHeight">缩略图的高度</param>
        /// <returns>返回缩略图的Image对象</returns>
        public static System.Drawing.Image GetThumbNailImage(System.Drawing.Image originalImage, int thumMaxWidth, int thumMaxHeight)
        {
            Size thumRealSize = Size.Empty;
            System.Drawing.Image newImage = originalImage;
            Graphics graphics = null;

            try
            {
                thumRealSize = getNewSize(thumMaxWidth, thumMaxHeight, originalImage.Width, originalImage.Height);
                newImage = new Bitmap(thumRealSize.Width, thumRealSize.Height);
                graphics = Graphics.FromImage(newImage);

                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;

                graphics.Clear(Color.Transparent);

                graphics.DrawImage(originalImage, new Rectangle(0, 0, thumRealSize.Width, thumRealSize.Height), new Rectangle(0, 0, originalImage.Width, originalImage.Height), GraphicsUnit.Pixel);
            }
            catch { }
            finally
            {
                if (graphics != null)
                {
                    graphics.Dispose();
                    graphics = null;
                }
            }

            return newImage;
        }
        /// <summary>
        /// 获取一个图片按等比例缩小后的大小。
        /// </summary>
        /// <param name="maxWidth">需要缩小到的宽度</param>
        /// <param name="maxHeight">需要缩小到的高度</param>
        /// <param name="imageOriginalWidth">图片的原始宽度</param>
        /// <param name="imageOriginalHeight">图片的原始高度</param>
        /// <returns>返回图片按等比例缩小后的实际大小</returns>
        public static Size getNewSize(int maxWidth, int maxHeight, int imageOriginalWidth, int imageOriginalHeight)
        {
            double w = 0.0;
            double h = 0.0;
            double sw = Convert.ToDouble(imageOriginalWidth);
            double sh = Convert.ToDouble(imageOriginalHeight); double mw = Convert.ToDouble(maxWidth);
            double mh = Convert.ToDouble(maxHeight);

            if (sw < mw && sh < mh)
            {
                w = sw;
                h = sh;
            }
            else if ((sw / sh) > (mw / mh))
            {
                w = maxWidth;
                h = (w * sh) / sw;
            }
            else
            {
                h = maxHeight;
                w = (h * sw) / sh;
            }

            return new Size(Convert.ToInt32(w), Convert.ToInt32(h));
        }


        /// <summary>
        /// 保存图片到本地
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="s">文件流</param>
        /// <returns></returns>
        public static bool saveImgByPath(string fileName, byte[] bytes)
        {
            bool bSuccess = false;
            try
            {
                Image img = Image.FromStream(BytesToStream(bytes));
                img.Save(fileName, ImageFormat.Jpeg);
                if (File.Exists(fileName))
                {
                    bSuccess = true;
                }
            }
            catch (Exception ex)
            {
                LogUtil.GetInstance().WriteDebugLog("error:SaveImgByPath=>" + ex.Message);
            }

            return bSuccess;
        }

        /// <summary>
        /// 保存图片到本地
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="s">文件流</param>
        /// <returns></returns>
        public static bool saveImgByPath(string fileName, Stream s)
        {
            bool bSuccess = false;
            try
            {
                Image img = Image.FromStream(s);

                img.Save(fileName, ImageFormat.Jpeg);
                if (File.Exists(fileName))
                {
                    bSuccess = true;
                }
            }
            catch (Exception ex)
            {
                LogUtil.GetInstance().WriteDebugLog("error:SaveImgByPath=>" + ex.Message);
            }

            return bSuccess;
        }


        /// <summary>
        /// get image's path by folder name(images)
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        public static string getImageUrl(string imagePath)
        {
            int startLength = imagePath.IndexOf("images") - 1;
            int endLength = imagePath.Length - imagePath.IndexOf("images") + 1;

            return imagePath.Substring(startLength, endLength).Replace("\\", "/");
        }
        /// <summary>
        /// get image's path by folder name(images)
        /// </summary>
        /// <param name="imagePath"></param>
        /// <returns></returns>
        public static string getFileUrl(string filePath)
        {
            int startLength = filePath.IndexOf(filePath) - 1;
            int endLength = filePath.Length - filePath.IndexOf(filePath) + 1;

            return filePath.Substring(startLength, endLength).Replace("\\", "/");
        }
        /// <summary>
        /// 保存图片到本地
        /// </summary>
        /// <param name="imgUrl"></param>
        /// <param name="localPath"></param>
        /// <returns></returns>
        public static string saveImgByPath(string imgUrl, string localPath, string refererDomain)
        {
            string _imgUrl = string.Empty;
            WebClient wc = new WebClient();
            wc.Headers.Add("Referer", refererDomain);
            if (!string.IsNullOrEmpty(imgUrl) && !string.IsNullOrEmpty(localPath))
            {
                wc.DownloadFile(imgUrl, localPath);
                _imgUrl = getImageUrl(localPath);
            }
            return _imgUrl;
        }
        /// <summary>
        /// 将 Stream 转成 byte[]
        /// </summary>
        public static byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            return bytes;
        }
        /// <summary>
        /// 将 byte[] 转成 Stream
        /// </summary>
        public static Stream BytesToStream(byte[] bytes)
        {
            Stream stream = new MemoryStream(bytes);
            return stream;
        }
        /// <summary>
        /// 获取图片Byte数据
        /// </summary>
        /// <param name="picPath">图片路径</param>
        /// <returns></returns>
        public static byte[] GetImageData(string picPath)
        {
            byte[] byteImg = null;
            if (null != picPath && picPath.Length != 0)
            {
                using (FileStream fs = new FileStream(picPath, FileMode.Open))
                {
                    byteImg = new byte[fs.Length];
                    fs.Read(byteImg, 0, byteImg.Length);
                }
            }
            return byteImg;
        }
        /// <summary>
        /// 获取图片Byte数据
        /// </summary>
        /// <param name="image">Image实例</param>
        /// <returns></returns>
        public static byte[] GetImageData(System.Drawing.Image image)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
                byte[] byteImg = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(byteImg, 0, byteImg.Length);

                return byteImg;
            }
        }
        /// <summary>
        /// 读取图片
        /// </summary>
        /// <param name="byteImg">byte数据</param>
        /// <returns></returns>
        public static System.Drawing.Image ReadImage(byte[] byteImg)
        {
            using (MemoryStream ms = new MemoryStream(byteImg))
            {
                Image img = Image.FromStream(ms);
                return img;
            }
        }
    }
}
